package com.thinkcms.security.license;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.thinkcms.core.api.BaseRedisService;
import com.thinkcms.core.config.ThinkCmsConfig;
import com.thinkcms.core.handler.CustomException;
import com.thinkcms.core.model.LicenseProperties;
import com.thinkcms.core.utils.ApiResult;
import com.thinkcms.core.utils.Checker;
import com.thinkcms.core.utils.RSAUtils;
import com.thinkcms.core.utils.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Slf4j
public class VerifyLicenseImpl implements VerifyLicense {

    private ThinkCmsConfig cmsConfig;

    public BaseRedisService baseRedisService;

    public VerifyLicenseImpl(){

    }
    public VerifyLicenseImpl( ThinkCmsConfig cmsConfig, BaseRedisService baseRedisService){
        this.cmsConfig=cmsConfig;
        this.baseRedisService=baseRedisService;
    }

    @Override
    public Boolean verify(String licensePath, Map<String,Object> propertie) throws Exception {
        if(!propertie.isEmpty()){
            LicenseProperties properties=JSON.parseObject(JSON.toJSONString(propertie), LicenseProperties.class);
            if(!propertie.containsKey(SecurityConstants.SIGNATURER) || Checker.BeBlank(propertie.get(SecurityConstants.SIGNATURER).toString())){
                log.error("20028:license证书不合法");
                throw new CustomException(ApiResult.result(20028));
            }
            String sign=propertie.get(SecurityConstants.SIGNATURER).toString();
            propertie.remove(SecurityConstants.SIGNATURER);
            try {
               boolean valid = RSAUtils.verify(propertie.toString().getBytes(), SecurityConstants.PUBLIC_KEY, sign);
                if(!valid){
                    log.error("20028:license证书不合法");
                    throw new CustomException(ApiResult.result(20028));
                }
            }catch (Exception e){
                throw new CustomException(ApiResult.result(20028));
            }
            propertie.put(SecurityConstants.SIGNATURER,sign);
            verifyDate(properties);
            verifyDomain(properties);
        }
        return true;
    }


    private void verifyDate( LicenseProperties properties){
        Date now = DateUtil.date();
        Date start=null,end=null;
        try {
            String[] startEnd=properties.getStartStopTime().split("~");
            start = DateUtil.parse(startEnd[0]);
            end = DateUtil.parse(startEnd[1]);
        }catch (Exception e){
            log.error("20029:license证书日期不合法");
            throw new CustomException(ApiResult.result(20029));
        }
        int isSatrt=DateUtil.compare(now,start);
        int isEnd=DateUtil.compare(now,end);
        if(isSatrt==-1){
            log.error("20034:license证书授权未生效");
            throw new CustomException(ApiResult.result(20034));
        }
        if(isEnd==1){
            log.error("20030:license证书授权已过期");
            throw new CustomException(ApiResult.result(20030));
        }
    }

    private void verifyDomain(LicenseProperties properties){
         if(!SecurityConstants.LICENSE_All_DOMAIN.equals(properties.getDomain())){
            String[] domins= properties.getDomain().split(SecurityConstants.LICENSE_DOMAIN_SPLIT);
            if(domins.length>0){
                List<String> domainList= Arrays.asList(domins);
                String siteDomain =  cmsConfig.getSiteDomain();
                String serverApi=cmsConfig.getServerApi();
                if(Checker.BeNotBlank(siteDomain)){
                    siteDomain=siteDomain.replace("http://","").trim();
                    boolean siteDomainIgnore = ignore(siteDomain);
                    if(!siteDomainIgnore){
                        if(!domainList.contains(siteDomain)){
                            log.error("20032:license授权域名不合法");
                            throw new CustomException(ApiResult.result(20032));
                        }
                    }
                }
                if(Checker.BeNotBlank(serverApi)){
                    serverApi=serverApi.replace("http://","").trim();
                    boolean serverApiIgnore = ignore(serverApi);
                    if(!serverApiIgnore){
                        if(!domainList.contains(serverApi)){
                            log.error("20032:license授权域名不合法");
                            throw new CustomException(ApiResult.result(20032));
                        }
                    }
                }
            }
         }
    }

    private boolean ignore(String domain){
        boolean ignore=domain.startsWith("http://127") || domain.startsWith("127") || domain.contains("localhost");
        return ignore;
    }

}
